package cn.iocoder.yudao.framework.handler;

import cn.iocoder.yudao.framework.cache.NettyWsUserChannelCacheService;
import cn.iocoder.yudao.framework.common.NettyFrameworkConfig;
import cn.iocoder.yudao.framework.handlermapping.NettyWsChannelContext;
import cn.iocoder.yudao.framework.handlermapping.NettyWsHandlerMappingManager;
import cn.iocoder.yudao.framework.message.ClientRequest;
import cn.iocoder.yudao.framework.prometheus.ws.WebSocketMessageMetrics;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;

public class NettyWsRequestDispatcherHandler extends ChannelInboundHandlerAdapter {

    private Logger logger = LoggerFactory.getLogger(NettyWsRequestDispatcherHandler.class);
    @Autowired
    private NettyWsUserChannelCacheService gameChannelService;
    @Autowired
    private NettyFrameworkConfig nettyFrameworkConfig;
    @Autowired
    private NettyWsUserChannelCacheService gameServerCacheService;

    @Resource
    private WebSocketMessageMetrics webSocketMessageMetrics;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof ClientRequest) {
            try {
                ClientRequest request = (ClientRequest) msg;

                NettyWsChannelContext gtx = new NettyWsChannelContext(ctx, request);

                NettyWsHandlerMappingManager nettyWsHandlerMappingManager = NettyWsHandlerMappingManager.getInstance();
                webSocketMessageMetrics.recordMetrics(request.getUri());
                nettyWsHandlerMappingManager.callMethod(gtx, request);
            } catch (Throwable e) {
                logger.error("处理客户端请求异常", e);
            }
        } else {
            logger.warn("收到非法请求数据：{}", msg.getClass().getName());
            ctx.fireChannelRead(msg);
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        //接收channel内部的一些事件
        if (evt instanceof IdleStateEvent) {
            logger.debug("连接空闲达到最大时间，断开连接,{}", ctx.channel().id().asShortText());
            ctx.channel().close();
        }
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        logger.error("服务器内部异常", cause);
    }
}
